package oa.util;

import java.util.Arrays;

/**
 * 生成随机验证码的字符串
 * @author admin
 *
 */
public class SecurityCode {

	//指定生成验证码的难度
	 public enum SecurityCodeLevel{Simple,Medium,Hard};
     /**
      * 产生默认的验证码
      */
	 public static String getSecurityCode(){
		 return getSecurityCode(4,SecurityCodeLevel.Hard,false);
	 }
	 /**
	  * 产生长度和难度任意的验证码
	  * @param length 长度
	  * @param level  难度
	  * @param isCanRepeat 是否能够出现重复的字符
	  * @return
	  */
	public static String getSecurityCode(int length, SecurityCodeLevel level,
			boolean isCanRepeat) {
		//随机抽取len个字符
		int len = length;
		//字符集合
		char[] codes={'0','1','2','3','4','5','6','7','8','9',
				'a','b','c','d','e','f','g','h','i','j','k',
				'l','m','n','o','p','q','r','s','t','u','v',
				'w','x','y','z','A','B','C','D','E','F','G',
				'H','I','J','K','L','M','N','O','P','Q','R',
				'S','T','U','V','W','X','Y','Z'};
		//根据不同难度截取字符数组
		if(level == SecurityCodeLevel.Simple)
		{
			codes=Arrays.copyOfRange(codes,0,10);//复制指定的数组到一个新的数组的指定范围
			
		}
		else if(level == SecurityCodeLevel.Medium)
		{
			codes=Arrays.copyOfRange(codes, 0, 36);
		}
		else
		{
			codes= Arrays.copyOfRange(codes, 0, 62);
		}
	    int n = codes.length; //字符集的长度
	    //抛出运行时异常
	    if(len > n && isCanRepeat==false) 
	    {
	    	throw new RuntimeException(String.format("调用SecurotyCode.getSevurityCode(%1$s,%2$s,%3$s)出现异常，"+
	                   "当isCanParent为%3$s时，传入的参数%1$%s不能大于%4$s", len,level,isCanRepeat,n));
	    }
	    
	    //存放取出来的字符
	    char[] result = new char[len];
	    //判断是否出现重复的字符
	    if(isCanRepeat)
	    {
	    	for(int i=0;i<result.length;i++)
	    	{
	    		//索引 0 到 n-1
	    		int r = (int) (Math.random()*n);
	    		//将result中的第i个元素设置为codes[r]存放的值
	    		result[i] = codes[r];
	    	}
	    }
	    else
	    {
	    	for(int i=0;i<result.length;i++)
	    	{
	    		//索引 0 到 n-1
	    		int r = (int) (Math.random()*n);
	    		//将result中的第i个元素设置为codes[r]存放的值
	    		result[i] = codes[r];
	    		//必须确保不会再次收取到那个字符，因为所有抽取的字符必须不同。
	    		//因此，这里用数组中的最后一个字符改写成codes[r],并将n减1
	    		codes[r] = codes[n-1];
	    		n--;
	    	}
	    }
	    
		return String.valueOf(result);
	}
	 
}
